#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int MAX=200005;
vector<int> G[MAX];
ll not_in[MAX], not_in_root[MAX];
ll top[MAX];
ll color[MAX];
ll get_paths(ll n) {
    return n*(n-1)/2;
}
ll ans;
ll DFS(int a) {
    int l=G[a].size();
    int now_top=top[color[a]];
    top[color[a]]=a;
    ll n_num=1;
    for (int i=0; i<l; i++) {
        not_in[a]=0;
        ll tmp=DFS(G[a][i]);
        ans-=get_paths(tmp-not_in[a]);
        n_num+=tmp;
    }
    (now_top?not_in[now_top]:not_in_root[color[a]])+=n_num;
    top[color[a]]=now_top;
    return n_num;
}
int main() {
    int cas=1;
    int n;
    int a,b;
    while (~scanf("%d", &n)) {
        for (int i=0; i<=n; i++) {
            not_in_root[i]=0;
            G[i].clear();
        }
        for (int i=1; i<=n; i++) {
            scanf("%lld", &color[i]);
        }
        for (int i=1; i<n; i++) {
            scanf("%d%d", &a, &b);
            if (a>b) swap(a,b);
            G[a].push_back(b);
        }
        ans=get_paths(n)*n;
        DFS(1);
        for (int i=1; i<=n; i++) ans-=get_paths(n-not_in_root[i]);
        printf("Case #%d: %lld\n", cas, ans);
        cas++;
    }
    return 0;
}
